home *** CD-ROM | disk | FTP | other *** search
/ NeXT Education Software Sampler 1992 Fall / NeXT Education Software Sampler 1992 Fall.iso / Programming / Source / NLoad / LoadView.m < prev    next >
Encoding:
Text File  |  1991-04-10  |  4.9 KB  |  230 lines

  1. #import <c.h>
  2. #import <libc.h>
  3. #import <stdio.h>
  4. #import <stdlib.h>
  5. #import <string.h>
  6.  
  7. #import <sys/time.h>
  8.  
  9. #import "LoadView.h"
  10. #import "LoadWrap.h"
  11.  
  12. #define LOCALUPDATE 10
  13.  
  14. #define MAXERRORS 3
  15.  
  16. extern int loadave();
  17.  
  18. void swap(float array[], int indexA, int indexB);
  19.  
  20. void timer(DPSTimedEntry, double, id);
  21.  
  22. /*---------------------------------------------------------------------------
  23. Besides creating the new frame, initialize variables to default settings.
  24. With the addition of the RPC/UDP support, some new variables were added.
  25. These variables, initial settings, and impact of the settings follow:
  26.  
  27.                   Initial
  28.     Variable      Setting   Comment
  29.     hostName      NULL      overridden later to host name,
  30.     nErrors       MAX...    forces the view white if the first client/server
  31.                             call fails; then records # consecutive errors,
  32.                             turning the view white after MAXERRORS,
  33. -----------------------------------------------------------------------------*/
  34.  
  35. @implementation LoadView
  36.  
  37. - initFrame:(const NXRect *) frameRect;
  38. {
  39.     const char *string;
  40.     int qLength;
  41.  
  42.     [(self = [super initFrame:frameRect]) allocateGState];
  43.  
  44.     qLength = ALL;
  45.     if ((string = getDefault("QueueLength")) && sscanf(string, "%d", &qLength) != 1) qLength = ALL;
  46.  
  47.     switch (qLength) {
  48.         case 15: queue = Q15MIN; break;
  49.         case  5: queue =  Q5MIN; break;
  50.         case  1: queue =  Q1MIN; break;
  51.         default: queue =    ALL; break;
  52.         }
  53.  
  54.     index = -1;
  55.     maxLoad = (float) 0.0;
  56.  
  57.     hostName = NULL;
  58.     
  59.     timedEntry = NULL;
  60.  
  61.     nErrors = MAXERRORS - 1; /* Forces view white if initial call fails. */
  62.  
  63.     return self;
  64. }
  65.  
  66. - drawSelf:(const NXRect *) rects :(int) rectCount
  67. {
  68.     int width = (int) bounds.size.width;
  69.     float currentLoad;
  70.     int oldIndex;
  71.  
  72.     oldIndex = index;
  73.     index = ++index % width;
  74.  
  75.     if ((currentLoad = [self getLoadAverage:index]) == (float) CERROR) {
  76.         index = oldIndex;
  77.         if (++nErrors == MAXERRORS) [self displayAll:NX_WHITE];
  78.         return self;
  79.         }
  80.     
  81.     if (index == --width) [[self moveArray] displayAll:NX_LTGRAY];
  82.     else
  83.         if (currentLoad > maxLoad || nErrors >= MAXERRORS) [self displayAll:NX_LTGRAY];
  84.         else [self drawOneLoad:index];
  85.         
  86.     nErrors = 0;
  87.     
  88.     return self;
  89. }
  90.  
  91. - free
  92. {
  93.     [self freeGState];
  94.     if (timedEntry != NULL) DPSRemoveTimedEntry(timedEntry);
  95.     
  96.     return [super free];
  97. }
  98.  
  99. - startTimer
  100. {
  101.     const char *string;
  102.     int time = LOCALUPDATE;
  103.  
  104.     if ((string = getDefault("LocalUpdateSeconds")) && sscanf(string, "%d", &time) != 1)
  105.         time = LOCALUPDATE;
  106.     
  107.     timedEntry = DPSAddTimedEntry((double) time, (DPSTimedEntryProc) &timer, self, NX_BASETHRESHOLD);
  108.     
  109.     return self;
  110. }
  111.  
  112. - (float) getLoadAverage:(int) offset 
  113. {
  114.     int i, scale, first = 0, last = QUEUES;
  115.     long vector[QUEUES];
  116.     float largest = 0.0;
  117.     
  118.     if ([self loadAverage:vector loadScale:&scale] == nil) return (float) CERROR;       
  119.     
  120.     if (queue != ALL) last = 1 + (first = queue);
  121.     
  122.     for (i = first; i < last; i++) {
  123.        load[offset][i] = vector[i] / (float) scale;
  124.        if (load[offset][i] > largest) largest = load[offset][i];
  125.     }
  126.     
  127.     return largest;
  128. }
  129.  
  130. - loadAverage:(long *) vector loadScale:(int *) scale
  131. {
  132.     if ((*scale = loadave(vector)) == CERROR) return nil;
  133.     else return self;
  134. }
  135.  
  136. - drawOneLoad:(int) offset 
  137. {
  138.     float vector[QUEUES], colors[QUEUES] = { NX_BLACK, NX_DKGRAY, NX_WHITE };
  139.     int i, j, first = 0, last = QUEUES;
  140.  
  141.     if (queue != ALL) last = 1 + (first = queue);
  142.  
  143.     for (i = first; i < last; i++) vector[i] = (bounds.size.height / maxLoad) * load[offset][i];
  144.  
  145.     if (queue == ALL) 
  146.         for (j = 1; j < QUEUES; j++)
  147.             for (i = 1; i < QUEUES; i++)
  148.                 if (vector[i] > vector[i - 1]) {
  149.                     swap(vector, i, i - 1);
  150.                     swap(colors, i, i - 1);
  151.                     }
  152.     
  153.     for (i = first; i < last; i++)
  154.         if (vector[i] > 0.0) drawload((float) offset, vector[i], colors[i]);
  155.  
  156.     return self;
  157. }
  158.  
  159. - moveArray
  160. {
  161.     int i, j, first = 0, last = QUEUES;
  162.     
  163.     index = (int) bounds.size.width / 2;
  164.     
  165.     if (queue != ALL) last = 1 + (first = queue);
  166.     
  167.     for (i = 0; i < index; i++)
  168.         for (j = first; j < last; j++)
  169.             load[i][j] = load[i + index][j];
  170.     
  171.     --index;
  172.     
  173.     return self;
  174. }
  175.  
  176. - displayAll:(float) color
  177. {
  178.     int i;
  179.  
  180.     maxLoad = (float) ceil((double) [self maxOfArray]);
  181.  
  182.     PSsetgray(color);
  183.     NXRectFill(&bounds);
  184.  
  185.     if (maxLoad > 1.0) {
  186.         float deltaScale = bounds.size.height / maxLoad;
  187.         for (i = 1; i < (int) maxLoad; i++)
  188.             drawline(rint(deltaScale * (float) i), bounds.size.width, NX_BLACK);
  189.         }
  190.  
  191.     for (i = 0; i <= index; i++) [self drawOneLoad:i];
  192.  
  193.     return self;
  194. }
  195.  
  196. - (float) maxOfArray
  197. {
  198.     int i, j, first = 0, last = QUEUES;
  199.     float largest = 0.0;
  200.  
  201.     if (queue != ALL) last = 1 + (first = queue);
  202.  
  203.     for (i = 0; i <= index; i++)
  204.         for (j = first; j < last; j++)
  205.             if (load[i][j] > largest) largest = load[i][j];
  206.         
  207.     return(largest);
  208. }
  209.  
  210. - setHostName:(const char *) name
  211. {
  212.     hostName = NXCopyStringBuffer(name);
  213.     
  214.     return self;
  215. }
  216.  
  217. void swap(float array[], int indexA, int indexB)
  218. {
  219.     float temp = array[indexA];
  220.     array[indexA] = array[indexB];
  221.     array[indexB] = temp;
  222. }
  223.  
  224. void timer(DPSTimedEntry teNumber, double now, id sender)
  225. {
  226.     [sender display];
  227. }
  228.  
  229. @end
  230.